fix(MessageBubble): clamp future-dated timestamps to now (supersedes #66)#86
Conversation
A future-dated wire timestamp (peer clock skew, or our own past clock) renders 'in 5 min' on a message that already arrived. Clamp the displayed relative time to min(timestamp, now) in Message.formattedTime so it shows 'Just now' instead. The absolute-time formatter in MessageDetailView is intentionally left alone — it shows raw protocol metadata. Adds MessageFormattedTimeTests (future -> now; past -> relative-past regression guard). Verified: build-for-testing + both tests pass on sim. Re-applies the iOS half of #60 fresh on current main — the original PR #66 predates the dual-backend refactor and is 78 commits stale with pbxproj + MessageBubble conflicts. Supersedes #66. Refs #60. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR clamps future-dated message timestamps to the current time before passing them to
Confidence Score: 5/5Safe to merge — the change is a small, self-contained clamp with no side effects on the absolute-time formatter or any other display path. The clamping logic captures No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["formattedTime called"] --> B["let now = Date()"]
B --> C{"timestamp > now?"}
C -- "Yes (future-dated wire ts)" --> D["display = now"]
C -- "No (past or present)" --> E["display = timestamp"]
D --> F["localizedString(for: now, relativeTo: now)\n→ 'Just now'"]
E --> G["localizedString(for: timestamp, relativeTo: now)\n→ '2 hr. ago', etc."]
Reviews (3): Last reviewed commit: "address greptile review feedback (greplo..." | Re-trigger Greptile |
|
@greptile review |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Make the past-timestamp test boundary-safe: 1 hr sits on the abbreviated formatter's min/hr rounding boundary, so the two independent Date() reads (test vs inside formattedTime) could straddle it and flake. Use a 2-hr mid-bucket offset and anchor 'now' once. Verified: both tests still pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Re-applies the iOS half of #60 fresh on current
main. Supersedes #66, which is 78 commits stale (predates the dual-backend refactor) and conflicts on bothMessageBubble.swiftandproject.pbxproj.Problem (still live on main)
Message.formattedTimeis still the unclampedso a future-dated wire timestamp (peer clock skew, or our own past clock) renders "in 5 min" on a message that has already arrived.
Fix
MessageBubble.swift: clamp the displayed relative time tomin(timestamp, now)→ renders "Just now" instead. The absolute-time formatter inMessageDetailViewis intentionally left alone (raw protocol metadata).MessageFormattedTimeTests.swift: future-dated → formatter's "now" string; past-dated → relative-past (regression guard). Wired intoColumbaAppTests.Verified
build-for-testingsucceeds and both tests pass on the simulator (Executed 2 tests, 0 failures).Refs #60(display half only; the out-of-order-messages half was a separate LXMF-swift ordering change).